package cn.jbolt.core.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.jbolt.core.base.JBoltMsg;
import cn.jbolt.core.bean.JBoltOfModuleInfo;
import cn.jbolt.core.bean.JsTreeBean;
import cn.jbolt.core.cache.JBoltApplicationCache;
import cn.jbolt.core.cache.JBoltPermissionCache;
import cn.jbolt.core.cache.JBoltTopnavCache;
import cn.jbolt.core.cache.JBoltUserCache;
import cn.jbolt.core.common.enums.JBoltSystemLogTargetType;
import cn.jbolt.core.db.sql.Sql;
import cn.jbolt.core.kit.JBoltSaasTenantKit;
import cn.jbolt.core.kit.JBoltUserKit;
import cn.jbolt.core.model.Application;
import cn.jbolt.core.model.Permission;
import cn.jbolt.core.model.TopnavMenu;
import cn.jbolt.core.model.User;
import cn.jbolt.core.model.base.BasePermission;
import cn.jbolt.core.service.base.JBoltBaseService;
import cn.jbolt.core.util.JBoltListMap;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Okv;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限Permission Service
 *
 * @ClassName: PermissionService
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2020年5月2日
 */
public class JBoltPermissionService extends JBoltBaseService<Permission> {
	public static final String PERMISSION_KEY_NONE = "NONE";
	protected Permission dao = new Permission().dao();
	@Inject
	protected JBoltRolePermissionService jboltRolePermissionService;
	@Inject
	protected JBoltTopnavMenuService jboltTopnavMenuService;

	@Override
	protected Permission dao() {
		return dao;
	}

	/**
	 * 得到所有permission 通过级别处理
	 *
	 * @return
	 */
	public List<Permission> getAllPermissionsWithLevel() {
		List<Permission> permissions = find(selectSql().orderBySortRank());
		return convertToModelTree(permissions, ID, "pid", (p) -> notOk(p.getPid()));
	}

	/**
	 * 得到 符合条件的数据 通过级别处理
	 *
	 * @return
	 */
	public List<Permission> getAdminPermissionsWithLevel(Integer ofMoudle,Long topnavId) {
		Sql sql = selectSql();
		List<Permission> permissions;
		sql.eq(Permission.OF_MODULE,ofMoudle);
		if (isOk(topnavId)) {
			sql.from(table(), "this");
			sql.leftJoin(jboltTopnavMenuService.table(), "tm", "tm.permission_id = this.id");
			sql.select("this.*").asc("this.sort_rank");
			sql.eq("tm.topnav_id", topnavId);
			List<Permission> temps = find(sql);
			permissions = new ArrayList<Permission>();
			if (isOk(temps)) {
				List<Permission> all = getAllPermissionsWithLevel();
				// 这是第一级拿到了
				for (Permission p : temps) {
					all.forEach(ap -> {
						if (ap.getPermissionKey().equals(p.getPermissionKey())) {
							permissions.add(ap);
						}
					});
				}
			}
		} else {
			sql.orderBySortRank();
			permissions = find(sql);
		}

		return convertToModelTree(permissions, ID, PID, (p) -> notOk(p.getPid()));
	}

	/**
	 * 得到所有permission 通过级别处理 options下拉数据专用
	 *
	 * @return
	 */
	public List<Permission> getAllPermissionsOptionsWithLevel() {
		List<Permission> permissions = find(selectSql().select("id,name,pid,permission_level").orderBySortRank());
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}

	/**
	 * 得到所有enable=true的permission 通过级别处理 options下拉数据专用
	 *
	 * @return
	 */
	public List<Permission> getAllEnablePermissionsOptionsWithLevel() {
		List<Permission> permissions = find(selectSql().select("id,name,pid,permission_level").enable().orderBySortRank());
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}

	/**
	 * 保存数据
	 *
	 * @param permission
	 * @return
	 */
	public Ret save(Permission permission) {
		if (permission == null || isOk(permission.getId())) {
			return fail(JBoltMsg.PARAM_ERROR);
		}
		if (notOk(permission.getPermissionKey())) {
			return fail("请设置权限KEY");
		}

		if (existsNameWithSameParent(-1L, permission.getName(), permission.getPid())) {
			return fail("同一父节点下资源【" + permission.getName() + "】已经存在，请更换");
		}
		if (exists("permission_key", permission.getPermissionKey())) {
			return fail("资源权限KEY【" + permission.getPermissionKey() + "】已经存在，请更换");
		}
		if (notOk(permission.getPid())) {
			permission.setPid(0L);
		}
		permission.setName(permission.getName().trim());
		permission.setSortRank(getNextSortRankByPid(permission.getPid()));
		processPermissionNewLevel(permission);
		processPermissionOfMoudle(permission);
		boolean success = permission.save();
		if (success) {
			JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
			// 添加日志
			addSaveSystemLog(permission.getId(), JBoltUserKit.getUserId(),
					permission.getName());
		}
		return success ? successWithData(permission) : fail();
	}

	/**
	 * 处理权限的所属模块信息
	 * @param permission
	 */
	protected void processPermissionOfMoudle(Permission permission) {
		if(notOk(permission.getOfModule()) || permission.getOfModule().intValue() == JBoltOfModuleInfo.PLATFORM_INNER_ADMIN){
			//如果没设置就是默认值
			permission.setOfModule(JBoltOfModuleInfo.PLATFORM_INNER_ADMIN);
			Application application = JBoltApplicationCache.me.getInnerPlatformApplication();
			permission.setOfModuleLink(application.getId().toString());
		}
	}

	/**
	 * 检测同一个pid下的name是否存在重复数据
	 *
	 * @param id
	 * @param pid
	 * @param pid
	 * @return
	 */
	private boolean existsNameWithSameParent(Long id, String name, Long pid) {
		Sql sql = selectSql().selectId().eqQM(NAME, PID).idNotEqQM().first();
		Long existId = queryLong(sql, name.trim(), pid, id);
		return isOk(existId);
	}

	/**
	 * 修改数据
	 *
	 * @param permission
	 * @return
	 */
	public Ret update(Permission permission) {
		if (permission == null || notOk(permission.getId()) || permission.getPid() == null
				|| notOk(permission.getName())) {
			return fail(JBoltMsg.PARAM_ERROR);
		}
		if (isOk(permission.getPid()) && permission.getPid().longValue() == permission.getId().longValue()) {
			return fail("上级权限不能是自身，请换一个");
		}
		Permission dbPermission = findById(permission.getId());
		// 如果数据库不存在
		if (dbPermission == null) {
			return fail(JBoltMsg.DATA_NOT_EXIST);
		}
		if (existsNameWithSameParent(permission.getId(), permission.getName(), permission.getPid())) {
			return fail("同一父节点下资源【" + permission.getName() + "】已经存在，请输入其它名称");
		}
		if (exists("permission_key", permission.getPermissionKey(), permission.getId())) {
			return fail("资源权限KEY【" + permission.getPermissionKey() + "】已经存在，请更换");
		}
		permission.setName(permission.getName().trim());
		// 其他地方调用传过来的一个sort请求 指明是排序后调用update
		Boolean sort = permission.getBoolean("sort");
		if (sort == null || notOk(permission.getPermissionLevel())) {
			processPermissionNewLevel(permission);
		}
		if(dbPermission.getPid() == null){
			dbPermission.setPid(0L);
		}
		if (dbPermission.getPid().longValue() != permission.getPid().longValue()) {
			permission.setSortRank(getNextSortRankByPid(permission.getPid()));
		}
		boolean success = permission.update();
		if (success) {
			if (dbPermission.getPid().longValue() != permission.getPid().longValue()) {
				updateSortRankAfterChangeParentNode(Okv.by(PID, dbPermission.getPid()), dbPermission.getSortRank());
				// 说明数据的父节点变更了 level相应的跟着变化了
				processSonItemLevel(permission.getId(), permission.getPermissionLevel());
			}
			// 需要处理菜单缓存
			JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
			// 如果是排序后update 日志会多加一部分说明
			if (sort != null) {
				addUpdateSystemLog(permission.getId(), JBoltUserKit.getUserId(), permission.getName(), "的顺序");
			} else {
				addUpdateSystemLog(permission.getId(), JBoltUserKit.getUserId(), permission.getName());
			}

		}
		return success ? successWithData(permission) : fail();
	}

	private void processSonItemLevel(Long id, int level) {
		List<Permission> permissions = getSons(id);
		if (isOk(permissions)) {
			permissions.forEach(p -> {
				p.setPermissionLevel(level + 1);
				processSonItemLevel(p.getId(), p.getPermissionLevel());
			});
			batchUpdate(permissions);
		}

	}

	private void processPermissionNewLevel(Permission permission) {
		if (notOk(permission.getPid())) {
			permission.setPermissionLevel(Permission.LEVEL_1);
		} else {
			int level = getParentLevel(permission.getPid());
			permission.setPermissionLevel(level + 1);
		}
	}

	private int getParentLevel(Long pid) {
		Permission permission = findById(pid);
		return permission.getPermissionLevel();
	}

	/**
	 * 删除
	 *
	 * @param id
	 * @return
	 */
	public Ret delPermissionById(Long id, boolean processRoleCache) {
		Ret ret = deleteById(id);
		if (ret.isOk()) {
			Permission permission = ret.getAs("data");
			// 删除后需要把此数据之后的数据更新顺序
			updateSortRankAfterDelete(Okv.by(PID, permission.getPid()), permission.getSortRank());
			// 删除子节点
			deleteByPid(id);
			// 根据被删除的permission去删掉给role上的数据
			Ret delret = jboltRolePermissionService.deleteByPermission(permission.getId());
			if (delret.isFail()) {
				return delret;
			}

			if (processRoleCache) {
				JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
			}
			// 添加日志
			addDeleteSystemLog(permission.getId(), JBoltUserKit.getUserId(),
					permission.getName());
		}
		return ret;
	}

	/**
	 * 删除子节点
	 *
	 * @param pid
	 */
	private void deleteByPid(Long pid) {
		List<Permission> permissions = getSons(pid);
		for (Permission permission : permissions) {
			delPermissionById(permission.getId(), false);
		}
	}

	/**
	 * 上移
	 *
	 * @param id
	 * @return
	 */
	public Ret up(Long id) {
		Permission permission = findById(id);
		if (permission == null) {
			return fail("数据不存在或已被删除");
		}
		Integer rank = permission.getSortRank();
		if (rank == null || rank <= 0) {
			return fail("顺序需要初始化");
		}
		if (rank == 1) {
			return fail("已经是第一个");
		}
		Permission upPermission = findFirst(Okv.by("sort_rank", rank - 1).set(PID, permission.getPid()));
		if (upPermission == null) {
			return fail("顺序需要初始化");
		}
		upPermission.setSortRank(rank);
		permission.setSortRank(rank - 1);
		upPermission.put("sort", true);
		permission.put("sort", true);
		update(upPermission);
		update(permission);
		return SUCCESS;
	}

	/**
	 * 下移
	 *
	 * @param id
	 * @return
	 */
	public Ret down(Long id) {
		Permission permission = findById(id);
		if (permission == null) {
			return fail("数据不存在或已被删除");
		}
		Integer rank = permission.getSortRank();
		if (rank == null || rank <= 0) {
			return fail("顺序需要初始化");
		}
		int max = getCount(Okv.by(PID, permission.getPid()));
		if (rank == max) {
			return fail("已经是最后一个");
		}
		Permission upPermissions = findFirst(Okv.by(SORT_RANK, rank + 1).set(PID, permission.getPid()));
		if (upPermissions == null) {
			return fail("顺序需要初始化");
		}
		upPermissions.setSortRank(rank);
		permission.setSortRank(rank + 1);
		upPermissions.put("sort", true);
		permission.put("sort", true);
		update(upPermissions);
		update(permission);
		return SUCCESS;
	}

	private void doInitOneRank(List<Permission> permissions) {
		if (notOk(permissions)) {
			return;
		}
		for (int i = 0; i < permissions.size(); i++) {
			permissions.get(i).setSortRank(i + 1);
		}
		batchUpdate(permissions);
		for (Permission f : permissions) {
//			deleteCacheById(f.getId());
//			deleteCacheByKey(f.getPermissionKey());
			// 继续向下递归
			List<Permission> items = getSonsOrderById(f.getId());
			doInitOneRank(items);

		}

	}

	/**
	 * 初始化排序
	 */
	public Ret initRank() {
		List<Permission> parents = getAllParentsOrderById();
		if (parents.size() > 0) {
			doInitOneRank(parents);
		}
		JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
		// 添加日志
		addUpdateSystemLog(null, JBoltUserKit.getUserId(), "全部", "初始化顺序");
		return SUCCESS;

	}

	/**
	 * 通过权限资源的KEY获取数据
	 *
	 * @param permissionKey
	 * @return
	 */
	public Permission getByPermissionkey(String permissionKey) {
		if (notOk(permissionKey)) {
			return null;
		}
		return findFirst(Okv.by("permission_key", permissionKey));
	}

	public List<Permission> getParentPermissionsWithLevel(Long roleId) {
		List<Permission> permissions = getPermissionsByRole(roleId);
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}

	private void processPermissionItems(List<Permission> permissions, List<Permission> parents) {
		JBoltListMap<String, Permission> map = new JBoltListMap<String, Permission>();
		for (Permission p : permissions) {
			map.addItem("p_" + p.getPid(), p);
		}
		for (Permission p : parents) {
			processSubItems(map, p);
		}

	}

	private void processSubItems(JBoltListMap<String, Permission> map, Permission permission) {
		List<Permission> items = map.get("p_" + permission.getId());
		if (items != null && items.size() > 0) {
			for (Permission item : items) {
				processSubItems(map, item);
			}
		}
		permission.putItems(items);
	}

	private void processParentPermission(List<Permission> permissions, List<Permission> parents) {
		Permission permission;
		for (int i = 0; i < permissions.size(); i++) {
			permission = permissions.get(i);
			if (permission.getPermissionLevel() == Permission.LEVEL_1 && notOk(permission.getPid())) {
				parents.add(permission);
				permissions.remove(i);
				i--;
			}
		}
	}

	/**
	 * 根据角色ID获取到绑定的permission
	 *
	 * @param roleId
	 * @return
	 */
	public List<Permission> getPermissionsByRole(Long roleId) {
		return find(selectSql().select("p.*").from(jboltRolePermissionService.table(), "rp")
				.leftJoin(table(), "p", "p.id=rp.permission_id").eq("rp.role_id", roleId).asc("p.sort_rank"));
	}

	/**
	 * 根据角色IDs获取到绑定的permission isMenu
	 *
	 * @param roleIds
	 * @param ofModule
	 * @return
	 */
	public List<Permission> getIsMenuPermissionsByRoles(String roleIds,Integer ofModule) {
		Sql sql = selectSql().distinct("p.id,"+getTableSelectColumnStrWithoutWithPre("p.","id","create_time","update_time")).from(jboltRolePermissionService.table(), "rp");
		sql.leftJoin(table(), "p", "permission_id","id");
		sql.eqIfOk("p.of_module",ofModule);
		sql.eq("p.is_menu", TRUE)
			.in("rp.role_id", roleIds)
			.asc("p.sort_rank");
		return find(sql);


//		List<Long> ids = query(selectSql().distinct("p.id").from(jboltRolePermissionService.table(), "rp")
//				.leftJoin(table(), "p", "p.id=rp.permission_id").eq("p.is_menu", TRUE).in("rp.role_id", roleIds)
//				.asc("p.sort_rank"));
//		if(notOk(ids)){
//			return null;
//		}
//		List<Permission> pers = new ArrayList<>();
//		Permission permission;
//		for(Long id:ids){
//			permission = JBoltPermissionCache.me.get(id);
//			if(permission!=null){
//				pers.add(permission);
//			}
//		}
//		return pers;
	}

	/**
	 * 切换是否为超管默认权限
	 *
	 * @param id
	 * @return
	 */
	public Ret toggleIsSystemAdminDefault(Long id) {
		Ret ret = toggleBoolean(id, "is_system_admin_default");
		if (ret.isOk()) {
			Permission selfPermission = ret.getAs("data");
			if (selfPermission.getIsSystemAdminDefault()) {
				processParentPermissionTrue(selfPermission.getPid());
				processSonPermissionTrue(selfPermission);
			} else {
				processSonPermissionFalse(selfPermission);
			}
			JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
			return successWithData(selfPermission.getIsSystemAdminDefault());
		}
		return ret;
	}

	/**
	 * 处理下级全部true
	 *
	 * @param permission
	 */
	private void processSonPermissionTrue(Permission permission) {
		List<Permission> sons = getSons(permission.getId());
		if (sons == null || sons.size() == 0) {
			return;
		}
		boolean success = false;
		for (Permission son : sons) {
			son.setIsSystemAdminDefault(true);
			success = son.update();
			if (success) {
				processSonPermissionTrue(son);
			}
		}
	}

	/**
	 * 处理下级全部false
	 *
	 * @param permission
	 */
	private void processSonPermissionFalse(Permission permission) {
		List<Permission> sons = getSons(permission.getId());
		if (sons == null || sons.size() == 0) {
			return;
		}
		boolean success = false;
		for (Permission son : sons) {
			son.setIsSystemAdminDefault(false);
			success = son.update();
			if (success) {
				processSonPermissionFalse(son);
			}
		}
	}

	/**
	 * 处理多级上级全部true
	 *
	 * @param pid
	 */
	private void processParentPermissionTrue(Long pid) {
		Permission permission = findById(pid);
		if (permission == null || permission.getIsSystemAdminDefault()) {
			return;
		}
		permission.setIsSystemAdminDefault(true);
		boolean success = permission.update();
		if (success) {
			if (permission.getPermissionLevel() == Permission.LEVEL_1) {
				return;
			}
			// 继续找关联
			processParentPermissionTrue(permission.getPid());
		}

	}

	public List<Permission> getIsMenuSystemAdminDefaultPermissions() {
		return getCommonList(Okv.by("is_system_admin_default", TRUE).set("is_menu", TRUE), SORT_RANK);
	}

	public List<Permission> getIsMenuSystemAdminDefaultListWithLevel() {
		List<Permission> permissions = getIsMenuSystemAdminDefaultPermissions();
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}

	/**
	 * 得到后台登录后显示的菜单
	 *
	 * @param roleIds
	 * @param ofModule
	 * @return
	 */
	public List<Permission> getMenusByRoles(String roleIds,Integer ofModule) {
		List<Permission> permissions = getIsMenuPermissionsByRoles(roleIds,ofModule);
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}

	/**
	 * 得到后台登录后显示的菜单
	 *
	 * @param roleIds
	 * @return
	 */
	public List<Permission> getMenusByRolesWithSystemAdminDefault(String roleIds) {
		if (StrKit.isBlank(roleIds)) {
			return getIsMenuSystemAdminDefaultListWithLevel();
		}
		List<Permission> permissions = getIsMenuPermissionsByRoles(roleIds,null);
		if (notOk(permissions)) {
			return getIsMenuSystemAdminDefaultListWithLevel();
		}
		List<Permission> adminDefaultPermissions = getIsMenuSystemAdminDefaultPermissions();
		if (isOk(adminDefaultPermissions)) {
			processMergePermissions(permissions, adminDefaultPermissions);
		}
		// 处理分级
		List<Permission> parents = new ArrayList<Permission>();
		processParentPermission(permissions, parents);
		if (parents.size() > 0 && permissions.size() > 0) {
			processPermissionItems(permissions, parents);
		}
		return parents;
	}


	/**
	 * 得到指定用户的所有有效的permissionKeys
	 *
	 * @param userId
	 * @param ofModule
	 * @return
	 */
	public List<String> getUserAllEnablePermissionKeys(Long userId,Integer ofModule) {
		if (notOk(userId)) {
			return null;
		}
		User user = JBoltUserCache.me.get(userId);
		if(user == null){
			LOG.error("参数异常 用户信息未找到");
			return null;
		}
		//获取RoleIds
		String roleIds = user.getRoles();
		if(notOk(roleIds)){
			if(user.getIsSystemAdmin()){
				//如果没有 就判断是不是
				return getAllEnableSystemAdminDefaultList();
			}
			return null;
		}
		//获取角色对应的可用权限KEYs
		List<String> permissionKeys = getAllEnablePermissionKeysByRoles(roleIds,ofModule);
		if (notOk(permissionKeys)) {
			if(user.getIsSystemAdmin()){
				//如果没有 就判断是不是
				return getAllEnableSystemAdminDefaultList();
			}
			return null;
		}
		List<String> adminDefaultPermissionKeys = getAllEnableSystemAdminDefaultList();
		if (isOk(adminDefaultPermissionKeys)) {
			Set<String> datas = new HashSet<String>(permissionKeys);
			datas.addAll(adminDefaultPermissionKeys);
			return new ArrayList<>(datas);
		}
		return permissionKeys;
	}

	public List<String> getAllEnableSystemAdminDefaultList() {
		return query(selectSql().select(Permission.PERMISSION_KEY).eq(Permission.IS_SYSTEM_ADMIN_DEFAULT,TRUE).enableEq(true));
	}
	/**
	 * 根据角色IDs获取到绑定的permissionKeys
	 *
	 * @param roleIds
	 * @param ofModule
	 * @return
	 */
	public List<String> getAllEnablePermissionKeysByRoles(String roleIds,Integer ofModule) {
		Sql sql = selectSql().distinct("p.permission_key,p.sort_rank").from(jboltRolePermissionService.table(), "rp");
		sql.leftJoin(table(), "p", "permission_id", "id");
		sql.eqIfOk("p.of_module", ofModule);
		sql.eq("p.enable", TRUE)
				.in("rp.role_id", roleIds)
				.asc("p.sort_rank");
		return query(sql);
	}

	/**
	 * 合并去重
	 *
	 * @param permissions
	 * @param adminDefaultPermissions
	 */
	private void processMergePermissions(List<Permission> permissions, List<Permission> adminDefaultPermissions) {
		Set<Long> set = permissions.stream().map(BasePermission::getId).collect(Collectors.toSet());
		permissions.addAll(adminDefaultPermissions.stream().filter(p->!set.contains(p.getId())).collect(Collectors.toList()));
		permissions.sort((o1, o2) -> o1.getSortRank() - o2.getSortRank());
	}

	/**
	 * 获取一级菜单 带着关联topnavmenu
	 *
	 * @return
	 */
	public List<Permission> getLevel1MenusJoinTopnavMenu() {
		List<Permission> permissions = getAllParents();
		List<TopnavMenu> menus = jboltTopnavMenuService.findAll();
		Map<String, Object> map = MapUtil.newHashMap(menus.size() * 2);
		for (TopnavMenu menu : menus) {
			map.put("mid_" + menu.getPermissionId(), menu.getTopnavId());
			map.put("mname_" + menu.getPermissionId(), JBoltTopnavCache.me.getName(menu.getTopnavId()));
		}
		for (Permission p : permissions) {
			p.put("topnavId", map.get("mid_" + p.getId()));
			p.put("topnavName", map.get("mname_" + p.getId()));
		}
		return permissions;
	}

	@Override
	protected int systemLogTargetType() {
		return JBoltSystemLogTargetType.PERMISSION.getValue();
	}

	/**
	 * 初始化租户的权限表初始数据
	 * @param tenantId
	 * @param tenantName
	 * @param tenantSn
	 */
	public void initTenantPermissions(String tenantId,String tenantName,String tenantSn) {
		if(StrKit.hasBlank(tenantId,tenantName,tenantSn)) {
			throw new RuntimeException("租户权限初始化创建需要传入所有参数不为空");
		}
		//模拟租户去给他处理初始化数据
		JBoltSaasTenantKit.me.useById(tenantId).call(()->startInitTenantPermissions(tenantId,tenantName,tenantSn));
	}

	private void startInitTenantPermissions(String tenantId,String tenantName,String tenantSn) {
		LOG.info("正在初始化租户：[{}:{}][租户Permission-权限资源]...",tenantName,tenantSn);
		LOG.info("检查租户：[{}:{}][租户Permission-权限资源]是否已经存在数据...",tenantName,tenantSn);
		int count = getCount();
		if(count>0) {
			LOG.info("检查租户：[{}:{}][租户Permission-权限资源]已经存在数据...",tenantName,tenantSn);
			return;
		}
		LOG.info("检查租户：[{}:{}][租户Permission-权限资源]尚未初始化...",tenantName,tenantSn);
		LOG.info("正在读取租户权限资源初始化JSON文件[{}]...","saas/tenant_permission_init.json");
		if(!FileUtil.exist("saas/tenant_permission_init.json")) {
			String msg = "[租户Permission-权限资源]相关初始化json文件未找到";
			LOG.error(msg);
			throw new RuntimeException(msg);
		}
		String json=FileUtil.readUtf8String("saas/tenant_permission_init.json");
		if(StrKit.isBlank(json)) {
			String msg = "[saas租户Permission-权限资源]相关初始化json文件中未读取到任何数据";
			LOG.error(msg);
			throw new RuntimeException(msg);
		}
		LOG.debug("正在解析并初始化租户权限资源...");
		JSONArray permissions=JSON.parseArray(json);
		if(permissions==null||permissions.size()==0) {
			String msg = "数据解析失败,无法进行[saas租户Permission-权限资源]初始化...";
			LOG.error(msg);
			throw new RuntimeException(msg);
		}
		LOG.info("数据解析成功，开始入库...");
		processPermissionsInsert(permissions);
		LOG.info("租户：[{}:{}][saas租户Permission-权限资源]数据入库完成...",tenantName,tenantSn);
	}

	private void processPermissionsInsert(JSONArray permissions) {
		if(permissions!=null&&permissions.size()>0) {
			JSONObject permissionObj;
			Permission permission;
			int size=permissions.size();
			for(int i=0;i<size;i++) {
				permissionObj=permissions.getJSONObject(i);
				permission=convertToPermission(permissionObj);
				LOG.info("正在初始化:租户权限[{}_{}]...",permission.getName(),permission.getPermissionKey());
				permission.save();
				processSonPermissionsInsert(permissionObj,permission);
			}
		}
	}

	private Permission convertToPermission(JSONObject permissionObj) {
		Permission permission=new Permission();
		permission.autoProcessIdValue();
		permission.setPid(0L);
		permission.setIcons(permissionObj.getString("icons"));
		permission.setIsMenu(permissionObj.getBoolean("isMenu"));
		permission.setIsSystemAdminDefault(permissionObj.getBoolean("isSystemAdminDefault"));
		permission.setIsTargetBlank(permissionObj.getBoolean("isTargetBlank"));
		permission.setOpenOption(permissionObj.getString("openOption"));
		permission.setOpenType(permissionObj.getInteger("openType"));
		permission.setPermissionKey(permissionObj.getString("permissionKey"));
		permission.setSortRank(permissionObj.getInteger("sortRank"));
		permission.setName(permissionObj.getString("name"));
		permission.setUrl(permissionObj.getString("url"));
		permission.setPermissionLevel(permissionObj.getInteger("permissionLevel"));
		return permission;
	}
	private void processSonPermissionsInsert(JSONObject permissionObj, Permission permission) {
		JSONArray sons=permissionObj.getJSONArray("items");
		if(sons!=null&&sons.size()>0) {
			int size=sons.size();
			JSONObject sonObj;
			Permission son;
			for(int i=0;i<size;i++) {
				sonObj=sons.getJSONObject(i);
				son=convertToPermission(sonObj);
				LOG.info("正在初始化:权限[{}_{}]...",son.getName(),son.getPermissionKey());
				son.setPid(permission.getId());
				son.save();
				processSonPermissionsInsert(sonObj,son);
			}
		}

	}

    public List<JsTreeBean> getAllEnableTreeDatas(boolean needOriginData) {
		List<Permission> enableList = find(selectSql().enable().orderBySortRank());
		return convertJsTree(enableList,null,2,SORT_RANK,needOriginData);
    }
	public List<JsTreeBean> getAllTreeDatas(boolean needOriginData) {
		List<Permission> enableList = find(selectSql().orderBySortRank());
		return convertJsTree(enableList,null,2,SORT_RANK,needOriginData);
    }

	@Override
	protected String afterToggleBoolean(Permission permission, String column, Kv kv) {
		if(column.equals(ENABLE)){
			if(permission.getEnable()){
				//将上级设置true
				if(isOk(permission.getPid())){
					changeParentsEnableTrue(permission.getPid());
				}
			}else{
				//将下级设置false
				changeSonsEnableFalse(permission.getId());
			}
			//更新缓存
			JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
		}

		return null;
	}

	private void changeSonsEnableFalse(Long id) {
		List<Permission> sons = getSons(id);
		if(isOk(sons)){
			sons.forEach(son->{
				son.setEnable(false);
				boolean success = son.update();
				if(!success){
					throw new RuntimeException("更新启用状态失败");
				}
				changeSonsEnableFalse(son.getId());
			});

		}
	}

	private void changeParentsEnableTrue(Long pid) {
		if(isOk(pid)){
			Permission parent = findById(pid);
			if(parent!=null){
				parent.setEnable(true);
				boolean success = parent.update();
				if(!success){
					throw new RuntimeException("更新启用状态失败");
				}
				changeParentsEnableTrue(parent.getPid());
			}
		}
	}

	/**
	 * 改变顺序
	 * @param id
	 * @param oriPid 原父节点
	 * @param newPid 新父节点
	 * @param oriRank 原顺序
	 * @param newRank 新顺序
	 * @return
	 */
	public Ret changeSortRank(Long id, Long oriPid, Long newPid,  Integer oriRank, Integer newRank) {
		if (Objects.equals(oriPid, newPid) && Objects.equals(oriRank, newRank)) {
			return SUCCESS;
		}
		if (Objects.equals(oriPid, newPid)) {
			//在原父元素内部移动
			updateSortRankByPid(id,oriPid, oriRank, newRank );

		} else {
			updateSortRankByPid(id, oriPid, oriRank, null);
			updateSortRankByPid(id, newPid, null, newRank);
		}
		// 需要处理菜单缓存
		JBoltPermissionCache.me.removeMenusAndPermissionsByRoleGroups();
		// 如果是排序后update 日志会多加一部分说明
		addUpdateSystemLog(id, JBoltUserKit.getUserId(), JBoltPermissionCache.me.get(id).getName(), "的顺序");
		return SUCCESS;
	}

	private void updateSortRankByPid(Long id, Long pid, Integer oriRank, Integer newRank) {
		Sql sql = updateSql().eq(PID, pid);
		if (newRank == null) {
			//newRank是null，代表它从原来的父元素里移出来了，原来排它后面的同级元素的顺序要-1，比如原来它排第6，后面789的元素现在变678了
			sql.gt(SORT_RANK, oriRank);
			sql.setSqlExpress(SORT_RANK, "sort_rank-1");
		} else if (oriRank == null) {

			// oriRank是null，代表它是新挪进来的，原来排它后面的同级元素的顺序要+1，比如它现在顺序是第6，原来678的就要变成789
			// 并且它的pid要变成新的pid

			Permission parent = JBoltPermissionCache.me.get(pid);
			Permission self = JBoltPermissionCache.me.get(id);
			int newLevel = (pid == 0 || parent == null) ? 1 : parent.getPermissionLevel() + 1;


			sql.ge(SORT_RANK, newRank).or().eq(ID, id);
			sql.setSqlExpress(SORT_RANK, "if(id="+id+", "+newRank+", sort_rank+1)")
					.setSqlExpress(PID, "if(id="+id+", "+pid+", pid)")
					.setSqlExpress(Permission.PERMISSION_LEVEL, "if(id="+id+", "+newLevel+", permission_level)");

			// 如果它的permission_level发生了变化，那么它的子元素的permission_level也要跟着变化
			if (Objects.equals(self.getPermissionLevel(), newLevel) == false ) {
				processSonItemLevel(id, newLevel);
			}
		} else if (oriRank > newRank) {
			//向下移动了，比如 原来6，现在3，那么需要 >=3 &&  <6的顺序+1，原来 345变成 456，然后原来的6 变成3
			sql.ge(SORT_RANK, newRank).le(SORT_RANK, oriRank);
			sql.setSqlExpress(SORT_RANK, "if(sort_rank="+oriRank+","+newRank+",sort_rank+1)");
		} else {
			//向上移动, 比如原来3 ，现在6，那么需要 >3 && <=6的顺序-1，原来的 456变成 345，然后原来的3 变成6
			sql.ge(SORT_RANK, oriRank).le(SORT_RANK, newRank);
			sql.setSqlExpress(SORT_RANK, "if(sort_rank="+oriRank+","+newRank+",sort_rank-1)");
		}
		update(sql);
	}



}
